home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime vr / vrscript / application files / comapplication.c next >
Encoding:
Text File  |  2000-06-23  |  32.9 KB  |  1,035 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for scripting application.
  6. //                This file is used for ***BOTH*** MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <31>         06/05/99    rtm        modified script-file specifying code in InitApplicationWindowObject to use new
  16. //                                    user preference settings
  17. //       <30>         05/28/99    rtm        added compiler flag BUG_2339989_OPEN in view of <28> and <29>
  18. //       <29>         05/27/99    rtm        added call to DoIdle in DoApplicationEventLoopAction, to compensate for change
  19. //                                    number <28>
  20. //       <28>         05/26/99    rtm        tweaked code for mcActionIdle in ApplicationMCActionFilterProc; allowing DoIdle
  21. //                                    to be called for VR movies caused stack overflow errors on Windows NT under QT 4.0
  22. //       <27>         12/17/98    rtm        added VRScript_SetCurrentDirectory call to InitApplicationWindowObject; now the
  23. //                                    initial current directory is that of the movie file
  24. //       <26>         12/03/98    rtm        added MoviesTask call to DoIdle for QuickTime movies, so they continue to play
  25. //                                    even while a dialog box (for instance, the About box) is displayed
  26. //       <25>         12/02/98    rtm        added previous movie/controller disposal code to DoApplicationEventLoopAction 
  27. //       <24>         11/23/98    rtm        HandleOpenDocumentAppleEvent now accepts dropped movie files too; added call
  28. //                                    to DoOpenCommandLineMovies back to InitApplication; the end result of all this
  29. //                                    is that both Mac and Windows apps will now open either movie files or scripts
  30. //                                    dropped onto the applicaiton icon
  31. //       <23>         11/14/98    rtm        InitApplication now calls VRScript_OpenCommandLineScriptFile instead of
  32. //                                    DoOpenCommandLineMovies, so we can drop scripts onto the application icon
  33. //                                    under Windows (MacOS was previously supported using AppleEvents)
  34. //       <22>         06/19/98    rtm        added mcActionMouseDown case to ApplicationMCActionFilterProc; also added
  35. //                                    other code for sprite track support
  36. //       <21>         03/12/98    rtm        added mcActionCustomButtonClick case to ApplicationMCActionFilterProc
  37. //       <20>         10/27/97    rtm        began adding support for QuickTime video effects
  38. //       <19>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  39. //       <18>         10/13/97    rtm        reworked HandleApplicationMenu to use menu item identifiers
  40. //       <17>         10/10/97    rtm        StopApplication now executes quitting-time commands for all open document windows;
  41. //                                    also, added phases for StopApplication
  42. //       <16>         09/24/97    rtm        upgraded to latest QuickTime VR headers
  43. //       <15>         09/18/97    rtm        added window-walking logic to DoApplicationEventLoopAction
  44. //       <14>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  45. //       <13>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  46. //       <12>         07/23/97    rtm        moved VRScript_CheckForTimedCommands back to DoIdle
  47. //       <11>         07/17/97    rtm        reworked DoIdle; added call to VR3DObjects_DoIdle
  48. //       <10>         07/15/97    rtm        moved VRScript_CheckForTimedCommands call from DoIdle to DoApplicationEventLoopAction
  49. //       <9>         07/14/97    rtm        fixed bug in DoIdle: put timer variable updates before _Check calls
  50. //       <8>         07/11/97    rtm        added DoApplicationEventLoopAction
  51. //       <7>         06/12/97    rtm        script file now can specify the movie file
  52. //       <6>         06/11/97    rtm        added handlers for core Apple events
  53. //       <5>         12/11/96    rtm        begun QuickTime movie work
  54. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  55. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  56. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  57. //       <1>         12/21/94    khs        first file
  58. //
  59. //////////
  60.  
  61. // header files
  62. #include "ComApplication.h"
  63.  
  64. // global variables for Macintosh code
  65. #if TARGET_OS_MAC
  66. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  67. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  68. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  69. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  70. #endif
  71.  
  72. // global variables for Windows code
  73. #if TARGET_OS_WIN32
  74. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  75. extern int                gNumWindowsOpen;
  76. extern LPSTR            gCmdLine;
  77. #endif
  78.  
  79. // global variables for common code
  80. long                    gMaxMilliSecToUse = 0L;        
  81. Boolean                    gQTVRMgrIsPresent = false;                // is the QuickTime VR Manager available?        
  82. long                    gQTVRMgrVersion = 0L;                    // the version of the QuickTime VR Manager (currently unused)
  83. Boolean                    gHasSoundSprockets = false;                // is SoundSprockets available?
  84. long                    gAbsoluteStartingTime = 0L;                // starting time, in ticks
  85. long                    gAbsoluteElapsedTime = 0L;                // total elapsed time, in ticks
  86. long                    gNodeStartingTime = 0L;                    // node starting time, in ticks
  87. long                    gNodeElapsedTime = 0L;                    // node elapsed time, in ticks
  88.  
  89. Boolean                    gHasQuickDraw3D = false;                // is QuickDraw 3D available?
  90. Boolean                    gHasQuickDraw3D15 = false;                // is QuickDraw 3D version 1.5 (or greater) available?
  91.  
  92. Boolean                    gHasQTVideoEffects = false;                // are the QuickTime video effects available?
  93.  
  94. // external variables
  95. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  96. extern char                gScriptFileName[kMaxFileNameLength];    // the name of the script file
  97. extern MovieController    gPreviousMC;                            // a controller that's been replaced by a call to ReplaceMainMovie                
  98. extern Movie            gPreviousMovie;                            // a movie that's been replaced by a call to ReplaceMainMovie        
  99. extern WindowPtr        gDebugWindow;                            // the verbose mode debug window
  100.  
  101. extern VRScriptPrefsHdl    gPreferences;                            // a handle to the global preferences record
  102. extern FSSpec            gAppFSSpec;                                // file specification for the application itself
  103.  
  104.  
  105. //////////
  106. //
  107. // InitApplication
  108. // Do any application-specific initialization.
  109. //
  110. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  111. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  112. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  113. //
  114. //////////
  115.  
  116. void InitApplication (UInt32 theStartPhase)
  117. {
  118.     // ***do any start-up activities that should occur before the MDI frame window is created
  119.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  120.  
  121.         // see if the QuickTime video effects are available
  122.         gHasQTVideoEffects = QTUtils_HasQuickTimeVideoEffects();
  123.     
  124.         // make sure that the QuickTime VR Manager is available in the present operating environment;
  125.         // if it is, get its version and initialize it
  126.         if (QTVRUtils_IsQTVRMgrInstalled()) {
  127.             gQTVRMgrIsPresent = true;
  128.             gQTVRMgrVersion = QTVRUtils_GetQTVRVersion();
  129.         
  130. #if TARGET_OS_WIN32
  131.             // initialize the QuickTime VR Manager
  132.             InitializeQTVR();
  133. #endif
  134.         }
  135.     
  136. #if TARGET_OS_MAC
  137.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  138.         InstallAppleEventHandlers();
  139. #endif
  140.  
  141.         VRHash_Init();                    // create the hash table
  142.         VRPrefs_Init();                    // initialize user preferences
  143.         VRSound_Init();                    // initialize sound capabilities
  144.         VRMoov_Init();                    // initialize embedded-movie capabilities
  145.  
  146. #if QD3D_AVAIL
  147.         VR3DObjects_Init();                // initialize 3D object capabilities
  148. #endif
  149.     
  150.         // get the application-launch starting time 
  151.         gAbsoluteStartingTime = TickCount();
  152.         
  153.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  154.  
  155.     // ***do any start-up activities that should occur after the MDI frame window is created
  156.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  157.         
  158. #if TARGET_OS_WIN32
  159.         // on Windows, open as *scripts* any text files specified on the command line
  160.         VRScript_OpenCommandLineScriptFile(gCmdLine);    
  161.                                         
  162.         // on Windows, open as *movies* any movie files specified on the command line
  163.         DoOpenCommandLineMovies(gCmdLine);                                    
  164. #endif
  165.     }    // end of kInitAppPhase_AfterCreateFrameWindow
  166.  
  167. }
  168.  
  169.  
  170. //////////
  171. //
  172. // StopApplication
  173. // Do any application-specific shut-down.
  174. //
  175. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  176. // *before* any open movie windows are destroyed or *after*.
  177. //
  178. //////////
  179.  
  180. void StopApplication (UInt32 theStopPhase)
  181. {
  182.     WindowReference            myWindow;
  183.     WindowObject            myWindowObject;
  184.     
  185.     // do any shut-down activities that should occur before the movie windows are destroyed
  186.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  187.  
  188.         // execute any quitting-time commands for all open document windows
  189.         myWindow = GetFrontMovieWindow();
  190.         while (myWindow != NULL) {
  191.         
  192.             myWindowObject = GetWindowObjectFromWindow(myWindow);
  193.             if (myWindowObject != NULL) {
  194.                 ApplicationDataHdl        myAppData;
  195.             
  196.                 myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  197.                 if (myAppData != NULL) {
  198.                     VRScriptAtQuitPtr    myPointer;
  199.                     
  200.                     myPointer = (VRScriptAtQuitPtr)(**myAppData).fListArray[kVREntry_QuitCommand];
  201.                     while (myPointer != NULL) {
  202.                         VRScript_ProcessScriptCommandLine(myWindowObject, myPointer->fCommandLine);
  203.                         myPointer = myPointer->fNextEntry;
  204.                     }
  205.                 }
  206.             }
  207.             
  208.             myWindow = GetNextMovieWindow(myWindow);
  209.         }
  210.     
  211.     }    // end of kStopAppPhase_BeforeDestroyWindows
  212.     
  213.     // do any shut-down activities that should occur after the movie windows are destroyed
  214.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  215.     
  216.         VRSound_Stop();                    // shut down sound processing
  217.         VRMoov_Stop();                    // shut down embedded-movie capabilities
  218.         VRPrefs_Stop();                    // shut down user preferences
  219.         VRHash_Stop();                    // dispose of our hash table
  220.  
  221. #if QD3D_AVAIL
  222.         VR3DObjects_Stop();                // shut down 3D object capabilities, if enabled
  223. #endif
  224.  
  225. #if !USE_SIOUX_FOR_DEBUG
  226.         // close the debug window, if it's open
  227.         if (gDebugWindow != NULL)
  228.             DisposeWindow(gDebugWindow);
  229. #endif
  230.         
  231. #if TARGET_OS_MAC
  232.         // dispose of routine descriptors for Apple event handlers
  233.         DisposeRoutineDescriptor(gHandleOpenAppAEUPP);
  234.         DisposeRoutineDescriptor(gHandleOpenDocAEUPP);
  235.         DisposeRoutineDescriptor(gHandlePrintDocAEUPP);
  236.         DisposeRoutineDescriptor(gHandleQuitAppAEUPP);
  237. #endif
  238.     
  239. #if TARGET_OS_WIN32
  240.         // terminate QuickTime VR Manager
  241.         if (gQTVRMgrIsPresent)
  242.             TerminateQTVR();
  243. #endif
  244.             
  245.     }    // end of kStopAppPhase_AfterDestroyWindows
  246.     
  247. }
  248.  
  249.  
  250. //////////
  251. //
  252. // DoIdle
  253. // Do any processing that can/should occur at idle time.
  254. //
  255. //////////
  256.  
  257. void DoIdle (WindowReference theWindow)
  258. {
  259.     WindowObject         myWindowObject = NULL;
  260.     GrafPtr             mySavedPort;
  261.  
  262.     GetPort(&mySavedPort);
  263.     MacSetPort(GetPortFromWindowReference(theWindow));
  264.     
  265.     // update our timer global variables; this also happens in DoApplicationEventLoopAction
  266.     gAbsoluteElapsedTime = TickCount() - gAbsoluteStartingTime; 
  267.     gNodeElapsedTime = TickCount() - gNodeStartingTime;
  268.     
  269.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  270.     if (myWindowObject != NULL) {
  271.         MovieController        myMC = NULL;
  272.         ApplicationDataHdl    myAppData = NULL;
  273.         Boolean                myNeedUpdate = false;
  274.     
  275.         myMC = (**myWindowObject).fController;
  276.         if (myMC != NULL) {
  277.             
  278. #if TARGET_OS_MAC
  279.             // restore the cursor to the arrow
  280.             // if it's outside the front movie window or outside the window's visible region
  281.             if (theWindow == GetFrontMovieWindow()) {
  282.                 Rect    myRect;
  283.                 Point    myPoint;
  284.                 
  285.                 GetMouse(&myPoint);
  286.                 MCGetControllerBoundsRect(myMC, &myRect);
  287.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  288.                     MacSetCursor(&qd.arrow);
  289.             }
  290. #endif
  291.         }
  292.         
  293.         // if the main window contains a QuickTime movie, give it some time
  294.         if ((**myWindowObject).fInstance == NULL)
  295.             MoviesTask((**myWindowObject).fMovie, 0L);
  296.  
  297.         // see whether we need to execute any time-triggered commands
  298.         VRScript_CheckForTimedCommands(myWindowObject);
  299.  
  300.         // see whether we need to execute any angle-triggered commands
  301.         VRScript_CheckForAngleCommands(myWindowObject);
  302.  
  303.         // if any view parameters have changed, we need to update window        
  304.         myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  305.         if (myAppData != NULL)
  306.             if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged) 
  307.                 myNeedUpdate = true;
  308.                 
  309.         // give any embedded QuickTime movies some processor time
  310.         myNeedUpdate |= VRMoov_DoIdle(myWindowObject);
  311.         
  312.         // give any QuickTime video effects some processor time
  313.         if (gHasQTVideoEffects)
  314.             myNeedUpdate |= VREffects_DoIdle(myWindowObject);
  315.         
  316. #if QD3D_AVAIL
  317.         // give 3D animation and texture-mapping some processor time
  318.         if (gHasQuickDraw3D)
  319.             myNeedUpdate |= VR3DObjects_DoIdle(myWindowObject);
  320. #endif
  321.  
  322.         if (myNeedUpdate)
  323.             if ((**myWindowObject).fInstance != NULL)
  324.                 QTVRUpdate((**myWindowObject).fInstance, kQTVRCurrentMode);
  325.     }
  326.  
  327.     MacSetPort(mySavedPort);
  328. }
  329.  
  330.  
  331. //////////
  332. //
  333. // DoUpdateWindow
  334. // Update the specified window.
  335. //
  336. //////////
  337.  
  338. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  339. {
  340. #pragma unused(theRefreshArea)
  341.     GrafPtr             mySavedPort;
  342.     
  343.     GetPort(&mySavedPort);
  344.     MacSetPort(GetPortFromWindowReference(theWindow));
  345.     
  346.     BeginUpdate(GetPortFromWindowReference(theWindow));
  347.     
  348.     // draw the movie controller and its movie
  349.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  350.     
  351.     EndUpdate(GetPortFromWindowReference(theWindow));
  352.     MacSetPort(mySavedPort);
  353. }
  354.  
  355.  
  356. //////////
  357. //
  358. // HandleContentClick
  359. // Handle mouse button clicks in the specified window.
  360. //
  361. //////////
  362.  
  363. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  364. {
  365. #pragma unused(theWindow, theEvent)
  366.  
  367.     //GrafPtr             mySavedPort;
  368.     
  369.     //GetPort(&mySavedPort);
  370.     //MacSetPort(GetPortFromWindowReference(theWindow));
  371.     
  372.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  373.  
  374.     //MacSetPort(mySavedPort);
  375. }
  376.  
  377.  
  378. //////////
  379. //
  380. // HandleApplicationKeyPress
  381. // Handle application-specific key presses.
  382. // Returns true if the key press was handled, false otherwise.
  383. //
  384. //////////
  385.  
  386. Boolean HandleApplicationKeyPress (char theCharCode)
  387. {
  388.     Boolean            isHandled = true;    // assume we'll handle the key press
  389.     QTVRInstance    myInstance;
  390.     
  391.     // make sure we can safely call the QTVR API
  392.     if (!gQTVRMgrIsPresent)
  393.         return(false);
  394.     
  395.     myInstance = GetQTVRInstanceFromFrontWindow();
  396.     if (myInstance == NULL)
  397.         return(false);
  398.     
  399.     switch (theCharCode) {
  400.         // take keypad keys as a nudge in the appropriate direction
  401.         case '1':    QTVRNudge(myInstance, kQTVRDownLeft);        break;
  402.         case '2':    QTVRNudge(myInstance, kQTVRDown);            break;
  403.         case '3':    QTVRNudge(myInstance, kQTVRDownRight);        break;
  404.         case '4':    QTVRNudge(myInstance, kQTVRLeft);            break;
  405.         case '6':    QTVRNudge(myInstance, kQTVRRight);            break;
  406.         case '7':    QTVRNudge(myInstance, kQTVRUpLeft);            break;
  407.         case '8':    QTVRNudge(myInstance, kQTVRUp);                break;
  408.         case '9':    QTVRNudge(myInstance, kQTVRUpRight);        break;    
  409.         default:
  410.             isHandled = false;
  411.             break;
  412.     }
  413.  
  414.     if (isHandled)
  415.         QTVRUpdate(myInstance, kQTVRCurrentMode);
  416.         
  417.     return(isHandled);
  418. }
  419.  
  420.  
  421. #if TARGET_OS_MAC
  422. //////////
  423. //
  424. // CreateMovieWindow
  425. // Create a window to display a movie in.
  426. //
  427. //////////
  428.  
  429. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  430. {
  431.     WindowRef            myWindow;
  432.         
  433.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  434.     return(myWindow);
  435. }
  436. #endif
  437.  
  438.  
  439. //////////
  440. //
  441. // HandleApplicationMenu
  442. // Handle selections in the application's menus.
  443. //
  444. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  445. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  446. // When called from MacOS, theMenuItem is constructed like this:
  447. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  448. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  449. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  450. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  451. //
  452. //////////
  453.  
  454. void HandleApplicationMenu (UInt16 theMenuItem)
  455. {
  456.     if (theMenuItem == IDM_PREFERENCES)
  457.         VRPrefs_ShowPrefsDialog();
  458. }
  459.  
  460.  
  461. //////////
  462. //
  463. // AdjustApplicationMenus
  464. // Adjust state of items in the application's menus.
  465. //
  466. //////////
  467.  
  468. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  469. {
  470. #pragma unused(theWindow)
  471.     MenuReference        myMenu;
  472.     
  473. #if TARGET_OS_WIN32
  474.     myMenu = theMenu;
  475. #elif TARGET_OS_MAC
  476.     myMenu = GetMenuHandle(mFile);
  477.  
  478. #if !USE_SIOUX_FOR_DEBUG
  479.     // do not allow the user to close the Debug window
  480.     if (GetFrontAppWindow() == gDebugWindow)
  481.         SetMenuItemState(myMenu, iClose, kDisableMenuItem);
  482. #endif
  483.  
  484. #endif    // #elif TARGET_OS_MAC
  485. }
  486.  
  487.  
  488. //////////
  489. //
  490. // DoApplicationEventLoopAction
  491. // Perform any application-specific event loop actions.
  492. //
  493. // Return true to indicate that we've completely handled the event here, false otherwise.
  494. //
  495. //////////
  496.  
  497. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  498. {    
  499.     WindowReference        myWindow = NULL;
  500.     WindowObject        myWindowObject = NULL;
  501.     
  502.     // update our timer global variables; this also happens in DoIdle
  503.     gAbsoluteElapsedTime = TickCount() - gAbsoluteStartingTime; 
  504.     gNodeElapsedTime = TickCount() - gNodeStartingTime;
  505.      
  506.     // check for completed sounds and movies in all open movie windows;
  507.     // also run the idle-time processing routine for all open windows
  508.     myWindow = GetFrontMovieWindow();
  509.  
  510.     while (myWindow != NULL) {
  511.         myWindowObject = GetWindowObjectFromWindow(myWindow);
  512.         if (myWindowObject != NULL) {
  513.         
  514.             // check for completed sounds and movies
  515.             VRSound_CheckForCompletedSounds(myWindowObject);
  516.             VRMoov_CheckForCompletedMovies(myWindowObject);
  517.             
  518. #if BUG_2339989_OPEN
  519.             // do any necessary idle-time processing
  520.             if (theEvent->what == nullEvent)
  521.                 DoIdle(myWindow);
  522. #endif
  523.         }
  524.  
  525.         myWindow = GetNextMovieWindow(myWindow);
  526.  
  527.     } // while
  528.     
  529.     // see whether we need to dispose of any replaced movie and controller
  530.     if (gPreviousMC != NULL) {
  531.         DisposeMovieController(gPreviousMC);
  532.         gPreviousMC = NULL;
  533.     }
  534.     
  535.     if (gPreviousMovie != NULL) {
  536.         DisposeMovie(gPreviousMovie);
  537.         gPreviousMovie = NULL;
  538.     }
  539.  
  540. #if USE_SIOUX_FOR_DEBUG
  541.     if (SIOUXHandleOneEvent(theEvent))
  542.         return(true);
  543. #endif
  544.  
  545.     return(false);    // we didn't intercept the event
  546. }
  547.  
  548.  
  549. //////////
  550. //
  551. // AddControllerFunctionality
  552. // Configure the movie controller.
  553. //
  554. //////////
  555.  
  556. void AddControllerFunctionality (MovieController theMC)
  557. {
  558.     long            myControllerFlags;
  559.     
  560.     // CLUT table use    
  561.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  562.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  563.  
  564.     // enable keyboard event handling    
  565.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  566.     
  567.     // disable drag support
  568.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  569. }
  570.  
  571.  
  572. //////////
  573. //
  574. // InitApplicationWindowObject
  575. // Do any application-specific initialization of the window object.
  576. //
  577. //////////
  578.  
  579. void InitApplicationWindowObject (WindowObject theWindowObject)
  580. {
  581.     Track                    myQTVRTrack;
  582.     Movie                    myMovie;
  583.     MovieController            myMC;
  584.     QTVRInstance            myInstance;
  585.     ApplicationDataHdl        myAppData;
  586.         
  587.     if (theWindowObject == NULL)
  588.         return;
  589.  
  590.     // make sure we can safely call the QTVR API
  591.     if (!gQTVRMgrIsPresent)
  592.         return;
  593.  
  594.     // find the QTVR track, if there is one
  595.     myMC = (**theWindowObject).fController;
  596.     myMovie = (**theWindowObject).fMovie;
  597.     if ((myMC == NULL) || (myMovie == NULL))
  598.         return;
  599.  
  600.     myQTVRTrack = QTVRGetQTVRTrack(myMovie, 1);
  601.     QTVRGetQTVRInstance(&myInstance, myQTVRTrack, myMC);
  602.     (**theWindowObject).fInstance = myInstance;
  603.  
  604.     // do any application-specific window configuration
  605.     if (myInstance != NULL) {
  606.         
  607.         // set unit to radians
  608.         QTVRSetAngularUnits(myInstance, kQTVRRadians);
  609.  
  610.         // do window configuration
  611.         myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord));
  612.         (**theWindowObject).fAppData = (Handle)myAppData;        
  613.         if (myAppData != NULL) {
  614.             
  615.             // initialize for sounds
  616.             VRSound_InitWindowData(theWindowObject);
  617.  
  618. #if QD3D_AVAIL
  619.             // initialize for 3D objects
  620.             if (gHasQuickDraw3D)
  621.                 VR3DObjects_InitWindowData(theWindowObject);
  622. #endif
  623.  
  624.             // initialize for QuickTime video effects
  625.             if (gHasQTVideoEffects)
  626.                 VREffects_InitWindowData(theWindowObject);
  627.  
  628.             // initialize for sprites
  629.             VRSprites_InitWindowData(theWindowObject);
  630.  
  631.             // allocate a routine descriptor for our prescreen routine                        
  632.             (**myAppData).fPrescreenProc = NewQTVRImagingCompleteProc(VRScript_PrescreenRoutine);    
  633.  
  634.             // allocate a routine descriptor for our back buffer procedure                        
  635.             (**myAppData).fBackBufferProc = NewQTVRBackBufferImagingProc(VRScript_BackBufferImagingProc);
  636.     
  637.             // install an intercept procedure and a prescreen procedure
  638.             VRScript_InstallInterceptRoutine(myInstance, theWindowObject);
  639.             VRScript_InstallPrescreenRoutine(myInstance, theWindowObject);
  640.  
  641.             // install node-entering and node-leaving procedures
  642.             QTVRSetEnteringNodeProc(myInstance, NewQTVREnteringNodeProc(VRScript_EnteringNodeProc), (SInt32)theWindowObject, 0);
  643.             QTVRSetLeavingNodeProc(myInstance, NewQTVRLeavingNodeProc(VRScript_LeavingNodeProc), (SInt32)theWindowObject, 0);
  644.             
  645.             // install hot spot procedures
  646.             VRScript_InstallHotSpotInterceptProc(myInstance, theWindowObject);
  647.             VRScript_InstallMouseOverHotSpotProc(myInstance, theWindowObject);
  648.                 
  649.             // read the command script file;
  650.             // if the user launched the application by dropping a script file onto the application's icon,
  651.             // then we already know the name of the script file to open (it's stored in gScriptFileName);
  652.             // otherwise, look for a script file in the location and with the name dictated by the user's
  653.             // current preferences
  654.             
  655.             if (strlen(gScriptFileName) > 0) {
  656.                 VRScript_OpenScriptFile(theWindowObject, gScriptFileName);
  657.                 gScriptFileName[0] = '\0';        // clear out gScriptFileName (we're finished with it for now)
  658.             } else {
  659.                 char    myScriptName[kMaxFileNameLength];
  660.                 FSSpec    myFSSpec;
  661.                 
  662.                 // set the current directory, based on the user's preferences
  663.                 switch ((**gPreferences).fScriptLocType) {
  664.                     case kVRPrefs_PromptUser: {
  665.                         SFTypeList            myTypeList = {kScriptFileType, 0, 0, 0};
  666.                         StandardFileReply    myReply;
  667.                     
  668.                         StandardGetFilePreview(NULL, 1, myTypeList, &myReply);
  669.                         if (myReply.sfGood) {
  670.                             VRScript_SetCurrentDirectory(&myReply.sfFile);
  671.                             BlockMove(&myReply.sfFile.name, myScriptName, myReply.sfFile.name[0]);
  672.                             myScriptName[myReply.sfFile.name[0]] = '\0';
  673.                         } else {
  674.                             myScriptName[0] = '\0';
  675.                         }
  676.                             
  677.                         break;
  678.                     }
  679.                     
  680.                     case kVRPrefs_DirOfMovieFile:
  681.                         VRScript_SetCurrentDirectory(&(**theWindowObject).fFileFSSpec);
  682.                         break;
  683.  
  684.                     case kVRPrefs_UserSpecifiedPath:
  685.                         FileUtils_MakeFSSpecForAnyFileInDir((**gPreferences).fScriptPathName, &myFSSpec);
  686.                         VRScript_SetCurrentDirectory(&myFSSpec);
  687.                         break;
  688.                         
  689.                     case kVRPrefs_DirOfApplication:
  690.                         VRScript_SetCurrentDirectory(&gAppFSSpec);
  691.                         break;
  692.                         
  693.                     default:
  694.                         break;
  695.                 }
  696.                 
  697.                 // set the script file name, based on the user's preferences
  698.                 switch ((**gPreferences).fScriptNameType) {
  699.                     case kVRPrefs_FileNamePlusTXT: {
  700.                         char *myNewName;
  701.                         char *myFileName = QTUtils_ConvertPascalToCString((**theWindowObject).fFileFSSpec.name);
  702.                         
  703.                         myNewName = FileUtils_ChangeFileNameSuffix(myFileName, kScriptFileSuffix);
  704.                         myScriptName[0] = '\0';
  705.                         strcat(myScriptName, myNewName);
  706.                         
  707.                         free(myFileName);
  708.                         free(myNewName);
  709.                         break;
  710.                     }    
  711.                     case kVRPrefs_UserSpecifiedName:
  712.                         BlockMove(&((**gPreferences).fScriptBaseName[1]), myScriptName, (**gPreferences).fScriptBaseName[0]);
  713.                         myScriptName[(**gPreferences).fScriptBaseName[0]] = '\0';
  714.                         break;
  715.                         
  716.                     default:
  717.                         break;
  718.                 }
  719.                 
  720.                 VRScript_OpenScriptFile(theWindowObject, myScriptName);
  721.             }
  722.             
  723.             // ***TESTING***
  724.             // this is a good place to test out commands without having to read them from a script file
  725.             if (false) {
  726.                 char    myCmdLine1[kMaxCmdLineLength] = "SetVerboseState 1 0";
  727.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtClickHSID 1 60 -1 1 MoveScreen#5.0#0.0#0";
  728.                 //char    myCmdLine3[kMaxCmdLineLength] = "AtClickHSID 1 40 -1 1 MoveScreen#5.0#0.0#0";
  729.                 //char    myCmdLine1[kMaxCmdLineLength] = "AtClickSprite 1 -1 2 SetSpriteMatrix#2#1.0#0.0#0.0#0.0#1.0#0.0#140.0#160.0#1.0#0";
  730.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtTime 300 1 1 0 0 1     0 ReplaceMainMovie#0#0#0#OfficePano";
  731.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtClickHS 1 50 -1 1 ReplaceMainMovie#0#2#0#file:///Meditations/WiredSprite.mov";
  732.                 //char    myCmdLine2[kMaxCmdLineLength] = "AtClickHS 1 50 -1 1 ReplaceMainMovie#0#0#0#Meditations:WiredSprite.mov";
  733.                 //char    myCmdLine3[kMaxCmdLineLength] = "OpenResourceFile    0            myCursors";
  734.                 //char    myCmdLine4[kMaxCmdLineLength] = "AtClickCustomButton    -1    -1    0        Beep";
  735.                 //char    myCmdLine4[kMaxCmdLineLength] = "PlaySceneQTMidi 144 1 1.0 0.0 0.0 180.0 0 0 2 myFile.mov";
  736.                 
  737.                 VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine1);
  738.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine2);
  739.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine3);
  740.                 //VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine4);
  741.             }
  742.             // ***TESTING***
  743.             
  744.             // initialize for first node
  745.             (**myAppData).fViewHasChanged = true;
  746.             (**myAppData).fSoundHasChanged = true;
  747.             
  748.             // node-entering procedure is NOT automatically called for the first node, so do it now....
  749.             VRScript_EnteringNodeProc(myInstance, QTVRGetCurrentNodeID(myInstance), theWindowObject);
  750.             
  751.             QTVRUpdate(myInstance, kQTVRCurrentMode);
  752.         }
  753.     }
  754. }
  755.  
  756.  
  757. //////////
  758. //
  759. // RemoveApplicationWindowObject
  760. // Do any application-specific clean-up of the window object.
  761. //
  762. //////////
  763.  
  764. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  765. {
  766.     ApplicationDataHdl    myAppData;
  767.     
  768.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  769.     if (myAppData == NULL)
  770.         return;
  771.  
  772.     VRSound_DumpWindowData(theWindowObject);
  773.     VRMoov_DumpNodeMovies(theWindowObject);
  774.     VRMoov_DumpSceneMovies(theWindowObject);
  775.  
  776. #if QD3D_AVAIL
  777.     // clean-up after QuickDraw 3D
  778.     if (gHasQuickDraw3D)
  779.         VR3DObjects_DumpWindowData(theWindowObject);
  780. #endif
  781.         
  782.     // clean-up after QuickTime video effects
  783.     if (gHasQTVideoEffects)
  784.         VREffects_DumpWindowData(theWindowObject);
  785.  
  786.     // clean-up sprites
  787.     VRSprites_DumpWindowData(theWindowObject);
  788.  
  789. #if TARGET_OS_MAC
  790.     // get rid of routine descriptors
  791.     DisposeRoutineDescriptor((**myAppData).fPrescreenProc);
  792.     DisposeRoutineDescriptor((**myAppData).fBackBufferProc);
  793. #endif
  794.         
  795.     // get rid of linked lists
  796.     VRScript_DeleteAllLists(theWindowObject);
  797.             
  798.     // get rid of window data
  799.     DisposeHandle((Handle)myAppData);
  800.         
  801.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  802.     // releases the window object itself
  803. }
  804.  
  805.  
  806. //////////
  807. //
  808. // ApplicationMCActionFilterProc 
  809. // Intercept some mc actions for the QuickTime or QuickTime VR movie controller.
  810. //
  811. // NOTE: The theRefCon parameter is a handle to a window object record.
  812. //
  813. //////////
  814.  
  815. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  816. {
  817. #pragma unused(theMC)
  818.  
  819.     Boolean                    isHandled = false;
  820.     WindowObject            myWindowObject = NULL;
  821.     ApplicationDataHdl        myAppData = NULL;
  822.     
  823.     if (theMC == NULL)
  824.         return(isHandled);
  825.         
  826.     myWindowObject = (WindowObject)theRefCon;
  827.     if (myWindowObject == NULL)
  828.         return(isHandled);
  829.         
  830.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  831.  
  832.     switch (theAction) {
  833.     
  834.         // handle window resizing
  835.         case  mcActionControllerSizeChanged:
  836.             SizeWindowToMovie(myWindowObject);
  837.             
  838.             // because the window size has changed, 
  839.             // we need to recalculate QD3D camera's aspect ratio and resize the QD3D draw context
  840. #if QD3D_AVAIL
  841.             if ((**myWindowObject).fInstance != NULL)
  842.                 if (gHasQuickDraw3D) {
  843.                     VR3DObjects_SetCameraAspectRatio(myWindowObject);                                 
  844.                     VR3DObjects_UpdateDrawContext(myWindowObject);                                 
  845.                     QTVRUpdate((**myWindowObject).fInstance, kQTVRCurrentMode);
  846.                 }
  847. #endif
  848.             break;
  849.             
  850.         // handle idle events
  851.         case mcActionIdle:
  852. #if BUG_2339989_OPEN
  853.             if ((**myWindowObject).fInstance == NULL)
  854. #endif
  855.                 DoIdle((**myWindowObject).fWindow);
  856.             break;
  857.             
  858.         // handle update events
  859.         case mcActionDraw:
  860.             break;
  861.  
  862.         // handle custom controller button clicks
  863.         case mcActionCustomButtonClick:
  864.             // good human interface design would have us track the cursor and process the mouse-down event
  865.             // only if the subsequent mouse-up event occurs inside of the custom button rectangle; however,
  866.             // we have no way of getting the custom button rectangle; so, we just blindly plow on ahead....
  867.             VRScript_CheckForClickCustomButtonCommands(myWindowObject, (EventRecord *)theParams);
  868.             break;
  869.             
  870.         // handle mouse-down events
  871.         case mcActionMouseDown:
  872.             // look for and handle sprite clicks, but only if the movie has a sprite track
  873.             if (myAppData != NULL)
  874.                 if ((**myAppData).fMovieHasSprites)
  875.                     isHandled = VRScript_CheckForClickSpriteCommands(myWindowObject, (EventRecord *)theParams);
  876.             break;
  877.             
  878.         default:
  879.             break;
  880.             
  881.     }    // switch (theAction)
  882.     
  883.     return(isHandled);    
  884. }
  885.  
  886.  
  887. #if TARGET_OS_MAC
  888. //////////
  889. //
  890. // InstallAppleEventHandlers 
  891. // Install handlers for Apple events.
  892. //
  893. //////////
  894.  
  895. void InstallAppleEventHandlers (void)
  896. {
  897.     long        myAttrs;
  898.     OSErr        myErr = noErr;
  899.     
  900.     // see whether the Apple Event Manager is available in the present operating environment;
  901.     // if it is, install handlers for the four required Apple events
  902.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  903.     if (myErr == noErr) {
  904.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  905.             // create routine descriptors for the Apple event handlers
  906.             gHandleOpenAppAEUPP = NewAEEventHandlerProc(HandleOpenApplicationAppleEvent);
  907.             gHandleOpenDocAEUPP = NewAEEventHandlerProc(HandleOpenDocumentAppleEvent);
  908.             gHandlePrintDocAEUPP = NewAEEventHandlerProc(HandlePrintDocumentAppleEvent);
  909.             gHandleQuitAppAEUPP = NewAEEventHandlerProc(HandleQuitApplicationAppleEvent);
  910.             
  911.             // install the handlers
  912.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  913.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  914.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  915.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  916.         }
  917.     }
  918. }
  919.         
  920.         
  921. //////////
  922. //
  923. // HandleOpenApplicationAppleEvent 
  924. // Handle the open-application Apple event.
  925. //
  926. //////////
  927.  
  928. PASCAL_RTN OSErr HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  929. {
  930. #pragma unused(theMessage, theReply, theRefcon)
  931.     
  932.     // we don't need to do anything special when opening the application
  933.     return(noErr);
  934. }
  935.  
  936.  
  937. //////////
  938. //
  939. // HandleOpenDocumentAppleEvent 
  940. // Handle the open-document Apple event. This is based on Inside Macintosh: IAC, pp. 4-15f.
  941. //
  942. // Here we process an Open Documents AE only for files of type kScriptFileType and creator kScriptFileCreator,
  943. // and for files of type MovieFileType.
  944. //
  945. //////////
  946.  
  947. PASCAL_RTN OSErr HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  948. {
  949. #pragma unused(theReply, theRefcon)
  950.  
  951.     long            myIndex;
  952.     long            myItemsInList;
  953.     AEKeyword        myKeyWd;
  954.     AEDescList          myDocList;
  955.     long            myActualSize;
  956.     DescType        myTypeCode;
  957.     FSSpec            myFSSpec;
  958.     OSErr            myIgnoreErr = noErr;
  959.     OSErr            myErr = noErr;
  960.     
  961.     // get the direct parameter and put it into myDocList
  962.     myDocList.dataHandle = NULL;
  963.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  964.     
  965.     // count the descriptor records in the list
  966.     if (myErr == noErr)
  967.         myErr = AECountItems(&myDocList, &myItemsInList);
  968.     else
  969.         myItemsInList = 0;
  970.     
  971.     // open each specified file
  972.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  973.         if (myErr == noErr) {
  974.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  975.             if (myErr == noErr) {
  976.                 FInfo        myFinderInfo;
  977.             
  978.                 // verify that the file type is kScriptFileType and the creator is kScriptFileCreator;
  979.                 // to do this, get the Finder information
  980.                 myErr = FSpGetFInfo(&myFSSpec, &myFinderInfo);    
  981.                 if (myErr == noErr) {
  982.                     if ((myFinderInfo.fdType == kScriptFileType) && (myFinderInfo.fdCreator == kScriptFileCreator))
  983.                         // we've got a script file; find the target QTVR movie and open it
  984.                         VRScript_FindAndOpenQTVRMovieFile(&myFSSpec);
  985.                         
  986.                     if (myFinderInfo.fdType == MovieFileType)
  987.                         // we've got a movie file; just open it
  988.                         DoCreateMovieWindow(NULL, &myFSSpec);
  989.                 }
  990.             }
  991.         }
  992.  
  993.     if (myDocList.dataHandle)
  994.         myIgnoreErr = AEDisposeDesc(&myDocList);
  995.     
  996.     // make sure we open the document in the foreground        
  997.     gAppInForeground = true;
  998.     return(myErr);
  999. }
  1000.  
  1001.  
  1002. //////////
  1003. //
  1004. // HandlePrintDocumentAppleEvent 
  1005. // Handle the print-document Apple event.
  1006. // NOT YET IMPLEMENTED: because we don't want to print our scripts, just act on them.
  1007. //
  1008. //////////
  1009.  
  1010. PASCAL_RTN OSErr HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  1011. {
  1012. #pragma unused(theMessage, theReply, theRefcon)
  1013.  
  1014.     return(errAEEventNotHandled);
  1015. }
  1016.  
  1017.  
  1018. //////////
  1019. //
  1020. // HandleQuitApplicationAppleEvent 
  1021. // Handle the quit-application Apple event.
  1022. //
  1023. //////////
  1024.  
  1025. PASCAL_RTN OSErr HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  1026. {
  1027. #pragma unused(theMessage, theReply, theRefcon)
  1028.  
  1029.     // close down the entire framework and application
  1030.     QuitFramework();
  1031.     return(noErr);
  1032. }
  1033. #endif    // TARGET_OS_MAC
  1034.  
  1035.